﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace theRift
{
    public class SimpleModel : DrawableGameComponent
    {
        protected Model model;
        protected Transformation transformation;

        // Servicse
        protected CameraManager cameraManager;
        protected LightManager lightManager;
        protected bool isInitialized;

        public Model Model
        {
            get { return model; }
        }

        public Transformation Transformation
        {
            get { return transformation; }
            set { transformation = value; }
        }

        public SimpleModel(Game game)
            : base(game)
        {
            this.transformation = new Transformation();

            this.isInitialized = false;
        }

        public override void Initialize()
        {
            cameraManager = Game.Services.GetService(typeof(CameraManager)) as CameraManager;
            lightManager = Game.Services.GetService(typeof(LightManager)) as LightManager;

            if (cameraManager == null)
                throw new InvalidOperationException(Error.NO_CAMERAMANAGER);

            if (lightManager == null)
                throw new InvalidOperationException(Error.NO_LIGHTMANAGER);

            isInitialized = true;

            base.Initialize();
        }

        public virtual void Load(string fileName)
        {
            if (!isInitialized)
                Initialize();

            model = Game.Content.Load<Model>("Models/" + fileName);
        }

        // Overriden by child classes
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect e in mesh.Effects)
                {
                    e.EnableDefaultLighting();
                    e.PreferPerPixelLighting = true;

                    e.Projection = cameraManager.ActiveCamera.Projection;
                    e.View = cameraManager.ActiveCamera.View;
                    e.World = transformation.Matrix * transforms[mesh.ParentBone.Index];
                }

                mesh.Draw();
            }
        }
    }
}
